package com.android.prpltalk;


import java.util.Arrays;
import java.util.Iterator;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Vector;

import com.android.prpltalk.R.id;
import com.android.prpltalk.R.layout;

import edu.stanford.prpl.api.BlobResource;
import edu.stanford.prpl.app.prpltalk.Message;
import edu.stanford.prpl.common.util.URIUtils;
import edu.stanford.prpl.app.prpltalk.Message;
import edu.stanford.prpl.app.prpltalk.PRPLTalk.AsynchCallback;
import edu.stanford.prpl.impl.BlobResourceImpl;

import android.util.Log;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

public class ChatPage extends Activity // implements Runnable
{

    private Vector<String> m_contactList;	
	
	/** ListView showing participants to this chat session. */
	private ListView chattersList;
	
	/** Button for sending data. */
	private ImageButton sendButton;	
	
	/** Button for closing this activity and session. */
	private ImageButton closeButton;
	
	/** List of already sent messages. */
	private ListView messagesSentList;
	
	/** Edit text for editing the message that must be sent. */
	private EditText messageToBeSent;
	
	/** Id of the session this activity is related to*/
	private String sessionId;
	
	/** Adapter used to fill up the message list */
	private ChatSessionAdapter sessionAdapter;
	private ChatSession chatSessionObj;
	// private ChatActivityHandler activityHandler;

    private static final int REFRESH_ID = Menu.FIRST;
    private static final String TAG = "MyActivity";	
    private static String thisUserName = "You";
    private static String thisUserEmail = "you@prpl.stanford.com";
    
    BlobResource resource;
    
	
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		//Thread.currentThread().getId();
        //myLogger.log(Logger.INFO, "onReceiveIntent called: My currentThread has this ID: " + Thread.currentThread().getId());

		super.onCreate(savedInstanceState);
		

	    //requestWindowFeature(Window.FEATURE_LEFT_ICON); 
	    setContentView(R.layout.chat_page);
	    
	    
	    //setFeatureDrawable(Window.FEATURE_LEFT_ICON, getResources().getDrawable(R.drawable.chat));		
		//myLogger.log(Logger.INFO, "onCreate called ...");
		sessionAdapter = new ChatSessionAdapter(getWindow().getLayoutInflater(), getResources());	
		sendButton = (ImageButton) findViewById(R.id.sendBtn);		
		sendButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) 
            {
            	String msgContent = messageToBeSent.getText().toString().trim();
            	// myLogger.log(Logger.INFO,"onClick(): send message:" + msgContent);
            	if (msgContent.length()>0)
            	{
            		// how does this work?
            		sendMessageToParticipants(msgContent);
            	}
            	messageToBeSent.setText("");
            	
            	Log.d(TAG, "Send Button Clicked!");
            }
        });		
		
		//retrieve the list
		chattersList = (ListView) findViewById(R.id.chattersList);		
		messageToBeSent = (EditText) findViewById(R.id.edit);
		messagesSentList = (ListView) findViewById(R.id.messagesListView);
		
		closeButton = (ImageButton) findViewById(R.id.closeBtn);
		closeButton.setOnClickListener(new View.OnClickListener(){
			public void onClick(View view)
			{
				// ChatSessionNotificationManager.getInstance().removeSessionNotification(sessionId);
				// MsnSessionManager.getInstance().removeMsnSession(sessionId);
				finish();
			}
		});
		
		
		// Get "Session ID"
		this.sessionId = savedInstanceState != null ? savedInstanceState.getString(ContactsPage.KEY_CHAT_SESSION_ID) 
                									: null;
        if (this.sessionId == null) 
        {
        	Bundle extras = getIntent().getExtras();            
        	this.sessionId = extras != null ? extras.getString(ContactsPage.KEY_CHAT_SESSION_ID) 
        									: null;
        }  		

        if (this.sessionId != null)
           this.chatSessionObj = ChatSessionManager.getInstance().retrieveSession(this.sessionId);
		

        
        // PRPL STUFF
		this.resource = new BlobResourceImpl(PrPlTalkActivity.prplTalk.sessionId2ResourceURI(this.sessionId), 
							   PrPlTalkActivity.prplAppClient);

		/*
		PrPlTalkActivity.prplTalk.setWatcher(sessionId, new AsychCallback() {
			@Override
			public void callback(String sessionId) 
			{
				Log.d(TAG, "AsycCallback called for " + sessionId + " . Thread Id is "
						+ Thread.currentThread().getId());
				//Message[] messages = PrPlTalkActivity.prplTalk.getMessages(sessionId, true);				
				updateMsgInChatWindow();
			}
		});
		
		*/

		// activityHandler = new ChatActivityHandler();			

	}

	
	/**
	 * Populates the GUI retrieving the sessionId from the intent that initiates the activity itself.
	 * The session Id is saved in the intent as an URI, whose fragment is the part we are interested in.
	 * <p>
	 * Please note that this method shall be called both when the activity is created for the first time and 
	 * when it is resumed from the background (that is, when it is in the foreground and the user switches to a new session
	 * by clicking the status bar notifications)
	 */
	@Override
	protected void onResume() 
	{
		// myLogger.log(Logger.INFO, "onResume() was called!" );
		// Intent i = getIntent();
		// Uri sessionIdUri = i.getData();
		// sessionId = sessionIdUri.getFragment();
		
		// Retrieves old active chat sessions that haven't been canceled
		this.chatSessionObj = ChatSessionManager.getInstance().retrieveSession(this.sessionId);
		setTitle(this.chatSessionObj.getSessionTitle());
		List<String> participantNames = this.chatSessionObj.getAllParticipantNames();
		
		ArrayAdapter<String> chattersListAdapter 
		= new ArrayAdapter<String>(this, R.layout.participant_layout, R.id.participantName, participantNames);
		chattersList.setAdapter(chattersListAdapter);
		// ChatSessionNotificationManager.getInstance().addNewSessionNotification(sessionId);
		messageToBeSent.setText("");

		this.refreshChatMsgWindow();
		
		Log.d(TAG, "Resumed ChatPage!");
		
		
		//Retrieve messages if the session already contains data
		// sessionAdapter.setNewSession(session);
		// messagesSentList.setAdapter(sessionAdapter);
		// MsnEventMgr.getInstance().registerEvent(MsnEvent.INCOMING_MESSAGE_EVENT, activityHandler);

		/*
        Thread thread = new Thread(this);
        thread.start();		
		
		*/
		
		super.onResume();
	}
	
	/**
	 * Called only when resuming an activity by clicking the status bar, just before <code> onResume() </code>
	 * <p>
	 * Sets the retrieved intent (containing info about the new session selected by the user) as the current one, to make 
	 * <code> onResume() </code> able to populate the GUI with the new data.
	 * 
	 * @param intent the intent launched when clicking on status bar notification (no new activity is created but the new intent is passed anyway)
	 */
	@Override
	protected void onNewIntent(Intent intent)
	{
		// myLogger.log(Logger.INFO, "WOW: onNewIntent was called!! \n Intent received was: " + intent.toString());
		setIntent(intent);
		super.onNewIntent(intent);
	}

	

	/**
	 * Called only when destroying the chat activity when closing the 
	 * chat window (both when clicking the close button or when going 
	 * back in activity stack with the back arrow).
	 * <p>
	 * It basically performs a disconnection from the service, sends 
	 * the closing message to the main activity and resets the ChatActivityUpdater
	 * to null (so the agent is aware that the chat activity is not visible). 
	 */
	@Override
	protected void onDestroy() 
	{
		super.onDestroy();		
		
		/*
		if (gateway != null)
		{
			gateway.disconnect(this);
			myLogger.log(Logger.FINER, "ChatActivity.onDestroy() : disconnected from MicroRuntimeService");
		}
		*/	
	}
	
	/**
	 * Gets the instance to the add-on's JadeGateway to be able to send messages to be sent to the 
	 * Jade agent. It's a callback, called after the connection to add-on's <code>MicroRuntimeService</code>
	 * 
	 * @param gw Instance of the JadeGateway retrieved after the connection
	 * @see ConnectionListener
	 */
	/*
	public void onConnected(JadeGateway gw) 
	{
		this.gateway = gw;
		myLogger.log(Logger.INFO, "onConnected(): SUCCESS!");
	}
	*/
	
	/**
	 * Dummy implementation for the ConnectionListener's onDisconnected
	 * 
	 * @see ConnectionListener
	 */
	public void onDisconnected() 
	{              }
	
	/**
	 * Sends a message to all participants of this session.
	 * <p>
	 * Instantiates a new SenderBehaviour object and sends it to the agent, together with message contents and receiver list, 
	 * then updates the message ListView.  
	 * 
	 * @param msgContent content of the message to be sent 
	 */
	private void sendMessageToParticipants(String msgContent)
	{
		// Retrieve a copy of the chat session
		ChatSession session = ChatSessionManager.getInstance().retrieveSession(sessionId);
		// set all participants as receivers
		List<String> receivers = session.getAllParticipantIds(); // 1 user for now?

		try
		{
			// Do PrPlTalk magic here
			if (sessionId != null)
			{
				PrPlTalkActivity.prplTalk.sendMessage(sessionId, "", msgContent);
				Log.d(TAG, "Sent a message: "+msgContent);
				// If notification does not work then... 
				this.refreshChatMsgWindow();
				Log.d(TAG, "Updated messages");
			}
			else
				Log.d(TAG, "You are currently not in any session");
			
			// End of PrPlTalk magic
			
			// Contact myContact = ContactManager.getInstance().getMyContact();
			// displayMsgInChatWindow(msgContent, myContact);			
		}
		catch(Exception e)
		{
			// myLogger.log(Logger.WARNING, e.getMessage());
		}
	}



	/**
	 * Defines an handler for UI events.
	 * 
	 */
	// private class ChatActivityHandler extends GuiEventHandler {
		
		/**
		 * Performs the update of the GUI. 
		 * It handles the arrival of a new message.
		 * <p>
		 * Two cases are possible:
		 * <ol>
		 * 	<li> incoming message is related to the current session and should be added to message list
		 * 	<li> incoming message is related to another session and a notification is to be shown
		 * </ol>
		 *  
		 * @param event the event that shall be notified to this listener to be handled 		 
		 */
		/*
		protected void processEvent(MsnEvent event) {
			
			String eventName = event.getName();
			
			//Handle case of new message
			if (eventName.equals(MsnEvent.INCOMING_MESSAGE_EVENT)){
				MsnSessionMessage msnMsg = (MsnSessionMessage) event.getParam(MsnEvent.INCOMING_MESSAGE_PARAM_MSG);
				String sessionId = (String) event.getParam(MsnEvent.INCOMING_MESSAGE_PARAM_SESSIONID);
				
				//check if the message is related to the same session we are currently in.
				//If so, add a new message to session udapter and update it
				if (sessionId.equals(ChatActivity.this.sessionId)){
					sessionAdapter.addMessageView(msnMsg);
					messagesSentList.setAdapter(sessionAdapter);
				} else {
					//if the incoming msg is not for our session, post a notification
					ChatSessionNotificationManager.getInstance().addNewMsgNotification(sessionId, msnMsg);
					Toast.makeText(ChatActivity.this, msnMsg.getSenderName() + " says: " + msnMsg.getMessageContent(), 3000).show();
				}
			} 
		}
		*/
	// }	

	
	/*
    public void run() 
    {
        pi_string = Pi.computePi(800).toString();
        handler.sendEmptyMessage(0);
    }	


    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) 
        {
            pd.dismiss();
            tv.setText(pi_string);
        }

    };	
	
	*/
	

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {    	
        super.onCreateOptionsMenu(menu);
        menu.add(0, REFRESH_ID, 0, R.string.refresh_chat)
           .setIcon(R.drawable.arrow_refresh);
        return true;
    }	


    
    
    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) 
    {
    	Intent i;
    	
        switch(item.getItemId()) 
        {
    		case REFRESH_ID:				
				Log.d(TAG, "Refreshing chat session (" + sessionId + ") ... ");            	

				refreshChatMsgWindow();
    			return true;
        }
       
        return super.onMenuItemSelected(featureId, item);
    }
    

    
    
  
	
	public void refreshChatMsgWindow()
	{
		Log.d(TAG, "Getting chat messages for sessionId=" + sessionId + " ... ");
		
		// Array of all messages so far apparently for this 'sessionId'
		Message[] messages = PrPlTalkActivity.prplTalk.getMessages(sessionId, true);
		
		if (messages != null)
		   Log.d(TAG, "Got "+messages.length+" chat messages for sessionId=" + sessionId + " ... ");
		else
		{
			Log.d(TAG, "MESSAGE OBJECT NULL for sessionId=" + sessionId + " ... ");
		   return;
		}
		
		// What do I do here now?
		
		// Clear out all old chat messages. We are GOING TO REBUILD EVERYTHING FROM SCRATCH AGAIN!
		chatSessionObj.clearAllMessages();
						
		// What is the nature of these Message objects here?
		for (int i = 0; i < messages.length; i++)
		{	
				/* 
				Address[] senders = messages[i].getFrom();
				long msgSentTime = messages[i].getSentDate().getTime();
				String senderEmail = senders[0].toString();
				Contact senderContact = ContactManager.getInstance().getContact(senderEmail);		
				String chatMsg = (String)messages[i].getContent();
				*/
				
				String senderName;
				String senderEmail = messages[i].getFrom().trim();
				String chatMsg = messages[i].getContent();
				long msgSentTime = messages[i].getSentDate().getTime();
				Contact senderContact = ContactManager.getInstance().getContact(senderEmail);
				if (senderContact == null)
				{
					// Log.d(TAG, "Contact obj for email="+senderEmail+" is NULL!");
					senderName = "Unknown";
				}
				else
				{	
					// Log.d(TAG, "Contact obj for email="+senderEmail+" is not null.");
					senderName = senderContact.getName();
				}
				
				Log.d(TAG, "Got Chat message='"+chatMsg+"' by "+senderName);
				
				// Setup message appearance in Chat Window
				ChatMessage newMessage 
				= new ChatMessage(chatMsg, senderName, senderEmail, msgSentTime);
				
				// Chat session
				chatSessionObj.addMessage(newMessage);
				
				// chatSessionObj.addMessage(message);
				// Add a new view to the adapter
				// sessionAdapter.addMessageView(message);
				// refresh the list
				// messagesSentList.setAdapter(sessionAdapter);	
		}
		
		// refresh the list of chat messages
		sessionAdapter.setNewSession(chatSessionObj);
		messagesSentList.setAdapter(sessionAdapter);			
	}
	
}
